home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / sgml / msdos / sgml07 / sgmlsasp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-27  |  5.1 KB  |  263 lines

  1. /* sgmlsasp.c
  2.    Translate sgmls output using ASP replacement file.
  3.  
  4.    Written by James Clark (jjc@jclark.com). */
  5.  
  6. #include "sgmlsasp.h"
  7. #include "sgmls.h"
  8. #include "replace.h"
  9. #include "getopt.h"
  10.  
  11. /* Non-zero if general (non-entity) names should be folded to upper case. */
  12. int fold_general_names = 1;
  13.  
  14. static char *program_name;
  15. static char last_char = '\n';
  16.  
  17. static void output_begin_line P((void));
  18. static void output_data P((struct sgmls_data *, int));
  19. static void output_pi P((char *));
  20. static void output_token P((char *));
  21. static void output_attribute P((struct sgmls_attribute *));
  22. static void output_replacement
  23.   P((struct replacement *, struct sgmls_attribute *));
  24. static void do_file P((FILE *, struct replacement_table *));
  25. static void usage P((void));
  26. static void input_error P((int, char *, unsigned long));
  27.  
  28. #define output_char(c) (last_char = (c), putchar(c))
  29.  
  30. int main(argc, argv)
  31.      int argc;
  32.      char **argv;
  33. {
  34.   struct replacement_table *tablep;
  35.   int i;
  36.   int opt;
  37.   program_name = argv[0];
  38.  
  39.   while ((opt = getopt(argc, argv, "n")) != EOF)
  40.     switch (opt) {
  41.     case 'n':
  42.       fold_general_names = 0;
  43.       break;
  44.     case '?':
  45.       usage();
  46.     default:
  47.       assert(0);
  48.     }
  49.   if (argc - optind <= 0)
  50.     usage();
  51.   tablep = make_replacement_table();
  52.   for (i = optind; i < argc; i++)
  53.     load_replacement_file(tablep, argv[i]);
  54.   (void)sgmls_set_errhandler(input_error);
  55.   do_file(stdin, tablep);
  56.   exit(0);
  57. }
  58.  
  59. static
  60. void usage()
  61. {
  62.   fprintf(stderr, "usage: %s [-n] replacement_file...\n", program_name);
  63.   exit(1);
  64. }
  65.  
  66. static
  67. void input_error(num, str, lineno)
  68.      int num;
  69.      char *str;
  70.      unsigned long lineno;
  71. {
  72.   error("Error at input line %lu: %s", lineno, str);
  73. }
  74.  
  75. static
  76. void do_file(fp, tablep)
  77.      FILE *fp;
  78.      struct replacement_table *tablep;
  79. {
  80.   struct sgmls *sp;
  81.   struct sgmls_event e;
  82.  
  83.   sp = sgmls_create(fp);
  84.   while (sgmls_next(sp, &e))
  85.     switch (e.type) {
  86.     case SGMLS_EVENT_DATA:
  87.       output_data(e.u.data.v, e.u.data.n);
  88.       break;
  89.     case SGMLS_EVENT_ENTITY:
  90.       /* XXX what should we do here? */
  91.       break;
  92.     case SGMLS_EVENT_PI:
  93.       output_pi(e.u.pi);
  94.       break;
  95.     case SGMLS_EVENT_START:
  96.       output_replacement(lookup_replacement(tablep,
  97.                         START_ELEMENT, e.u.start.gi),
  98.              e.u.start.attributes);
  99.       sgmls_free_attributes(e.u.start.attributes);
  100.       break;
  101.     case SGMLS_EVENT_END:
  102.       output_replacement(lookup_replacement(tablep, END_ELEMENT, e.u.end.gi),
  103.              0);
  104.       break;
  105.     case SGMLS_EVENT_SUBSTART:
  106.       break;
  107.     case SGMLS_EVENT_SUBEND:
  108.       break;
  109.     default:
  110.       abort();
  111.     }
  112.   sgmls_free(sp);
  113. }
  114.  
  115. static
  116. void output_data(v, n)
  117. struct sgmls_data *v;
  118. int n;
  119. {
  120.   int i;
  121.  
  122.   for (i = 0; i < n; i++) {
  123.     char *s = v[i].s;
  124.     int len = v[i].len;
  125.     for (; len > 0; len--, s++)
  126.       output_char(*s);
  127.   }
  128. }
  129.  
  130. static
  131. void output_pi(s)
  132.      char *s;
  133. {
  134.   for (; *s; s++)
  135.     output_char(*s);
  136. }
  137.  
  138. static
  139. void output_replacement(repl, attributes)
  140. struct replacement *repl;
  141. struct sgmls_attribute *attributes;
  142. {
  143.   struct replacement_item *p;
  144.   struct sgmls_attribute *a;
  145.   int i;
  146.  
  147.   if (!repl)
  148.     return;
  149.   if (repl->flags & NEWLINE_BEGIN)
  150.     output_begin_line();
  151.   
  152.   for (p = repl->items; p; p = p->next)
  153.     switch (p->type) {
  154.     case DATA_REPL:
  155.       for (i = 0; i < p->u.data.n; i++)
  156.     output_char(p->u.data.s[i]);
  157.       break;
  158.     case ATTR_REPL:
  159.       for (a = attributes; a; a = a->next)
  160.     if (strcmp(a->name, p->u.attr) == 0) {
  161.       output_attribute(a);
  162.       break;
  163.     }
  164.       break;
  165.     default:
  166.       abort();
  167.     }
  168.  
  169.   if (repl->flags & NEWLINE_END)
  170.     output_begin_line();
  171. }
  172.  
  173. static
  174. void output_attribute(p)
  175. struct sgmls_attribute *p;
  176. {
  177.   switch (p->type) {
  178.   case SGMLS_ATTR_IMPLIED:
  179.     break;
  180.   case SGMLS_ATTR_CDATA:
  181.     output_data(p->value.data.v, p->value.data.n);
  182.     break;
  183.   case SGMLS_ATTR_TOKEN:
  184.   case SGMLS_ATTR_ID:
  185.   case SGMLS_ATTR_IDREF:
  186.     {
  187.       char **token = p->value.token.v;
  188.       int n = p->value.token.n;
  189.       
  190.       if (n > 0) {
  191.     int i;
  192.     output_token(token[0]);
  193.     for (i = 1; i < n; i++) {
  194.       output_char(' ');
  195.       output_token(token[i]);
  196.     }
  197.       }
  198.     }
  199.     break;
  200.   case SGMLS_ATTR_ENTITY:
  201.     {
  202.       struct sgmls_entity **v = p->value.entity.v;
  203.       int n = p->value.entity.n;
  204.       int i;
  205.  
  206.       for (i = 0; i < n; i++) {
  207.     if (i > 0)
  208.       output_char(' ');
  209.     output_token(v[i]->is_internal
  210.              ? v[i]->u.internal.name
  211.              : v[i]->u.external.name);
  212.       }
  213.     }
  214.     break;
  215.   case SGMLS_ATTR_NOTATION:
  216.     if (p->value.notation)
  217.       output_token(p->value.notation->name);
  218.     break;
  219.   default:
  220.     abort();
  221.   }
  222. }
  223.  
  224. static
  225. void output_token(s)
  226.      char *s;
  227. {
  228.   for (; *s; s++)
  229.     output_char(*s);
  230. }
  231.  
  232. static
  233. void output_begin_line()
  234. {
  235.   if (last_char != '\n')
  236.     output_char('\n');
  237. }
  238.  
  239. #ifdef VARARGS
  240. void error(va_alist) va_dcl
  241. #else
  242. void error(char *message,...)
  243. #endif
  244. {
  245. #ifdef VARARGS
  246.      char *message;
  247. #endif
  248.      va_list ap;
  249.      
  250.      fprintf(stderr, "%s: ", program_name);
  251. #ifdef VARARGS
  252.      va_start(ap);
  253.      message = va_arg(ap, char *);
  254. #else
  255.      va_start(ap, message);
  256. #endif
  257.      vfprintf(stderr, message, ap);
  258.      va_end(ap);
  259.      fputc('\n', stderr);
  260.      fflush(stderr);
  261.      exit(EXIT_FAILURE);
  262. }
  263.